<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/3/20
 * Time: 11:50
 */

namespace Game\Services\Client;
use Game\Config\Config;
use Game\Lib\CodeConst;
use Game\Lib\G_CONST;
use Game\Lib\Game;
use Game\Lib\OPT_CONST;
use Game\Lib\Redis_Const;
use Game\Services\BaseOperation;
use Game\Services\GameData;
use Game\Services\GatewayService;
use Game\Services\MysqlService;
use Game\Services\RedisService;
use Game\Services\Tools;

class RoomOperation extends BaseOperation {

    public function createRoom($arrData){
        $data 			= $arrData['data'];
        $operation 		= $arrData['operation'];
        $account_id 	= $arrData['account_id'];
        $client_id 		= $arrData['client_id'];
        $session 		= $arrData['session'];
        if(false == Tools::getInstance()->checkRequestSession($account_id,$session)){
            return OPT_CONST::NO_RETURN;
        }

        //底分
        if(!isset($data['default_score']) || !in_array($data['default_score'], [2,4,8,10,25,20,50]) ){
            $this->logMessage('error', "function(createRoom):lack of default_score"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"default_score");
        }
        if(!isset($data['data_key']) || trim($data['data_key']) == G_CONST::EMPTY_STRING) {
            $this->logMessage('error', "function(createRoom):lack of data_key"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"data_key");
        }
        if(!isset($data['chip_type'])){
            $this->logMessage('error', "function(createRoom):lack of chip_type"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"chip_type");
        }
        if(!isset($data['disable_pk_score'])|| !in_array($data['upper_limit'], [0,100,200,500])) {
            $this->logMessage('error', "function(createRoom):lack of disable_pk_score"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"disable_pk_score");
        }
        if(!isset($data['disable_pk_men'])) {
            $this->logMessage('error', "function(createRoom):lack of disable_pk_men"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"disable_pk_men");
        }
        if(!isset($data['upper_limit']) || !in_array($data['upper_limit'], [0,500,1000,2000]) ) {
            $this->logMessage('error', "function(createRoom):lack of upper_limit"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"upper_limit");
        }
        if(!isset($data['xipai_score'])) {
            $this->logMessage('error', "function(createRoom):lack of xipai_score"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"xipai_score");
        }
        if (!isset($data['disable_look'])){
            $this->logMessage('error', "function(createRoom):lack of disable_look"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"disable_look");
        }
//        if(!isset($data['ticket_count'])) {
//            $this->logMessage('error', "function(createRoom):lack of ticket_count"." in file".__FILE__." on Line ".__LINE__);
//            return $this->_missingPrameterArr($operation,"ticket_count");
//        }
        if (!isset($data['player_count']) || !isset( Game::Ticket_Count[$data['player_count']])){
            $this->logMessage('error', "function(createRoom):lack of player_count"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"player_count");
        }
        $game_ticket = Game::Ticket_Count[$data['player_count']];

        if (!isset($data['total_num']) || !isset($game_ticket[$data['total_num']])){
            $this->logMessage('error', "function(createRoom):lack of total_num"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"total_num");
        }
        // 消耗房卡数量
        $spend_ticket_count = $game_ticket[$data['total_num']];

        //获取维护公告
        $alert_type = -1;
        $announcement_result = MysqlService::getInstance()->getGameAnnouncement($account_id);
        if(is_array($announcement_result)) {
            $alert_type = $announcement_result['alert_type'];
            $alert_text = $announcement_result['alert_text'];
        }
        if($alert_type == 4) {
            $result['alert_type'] = $alert_type;
            return array("result"=>CodeConst::Error_Announcement,"operation"=>$operation,"data"=>$result,"result_message"=>$alert_text);
        }

        //判断房卡余额
        $my_ticket_count = MysqlService::getInstance()->getTicketCount($account_id);
        $this->writeLog("($account_id) 房卡:" . $my_ticket_count);
        if($my_ticket_count < $spend_ticket_count){
            $this->writeLog("($account_id) 房卡不足");
            $result['alert_type'] = 1;	//1房卡不足
            return array("result"=> CodeConst::Error_TicketInsufficient, "operation"=>$operation, "data"=>$result,"result_message"=>"房卡不足");
        }

        //判断房间申请记录是否存在
        $roomInfo =  MysqlService::getInstance()->getRoomByDataKey($data['data_key']);
        if(!is_array($roomInfo) || count($roomInfo) == 0 ) {
            //创建房间
            $roomInfo = MysqlService::getInstance()->createRoomData($account_id, $data['data_key']);
            if (!$roomInfo){
                $this->logMessage('error', "function(createRoom):用户[".$account_id."] 创建房间失败："." in file".__FILE__." on Line ".__LINE__);
                return array("result"=>CodeConst::Error_RoomCreateFail,"operation"=>$operation,"data"=>[],"result_message"=>"创建房间失败");
            }
            $roomInfo["password"] = RedisService::getInstance()->generalRoomPassword($roomInfo['room_id']);
            MysqlService::getInstance()->updateRoomPassword($roomInfo['room_id'], $roomInfo["password"]);
        }
        $room_id = $roomInfo['room_id'];
        //添加房间信息到redis
        $r_mkv[Redis_Const::Room_Field_Number] = $roomInfo['room_number'];	//房间号
        $r_mkv[Redis_Const::Room_Field_GameRound] = 1;			//游戏轮数
        $r_mkv[Redis_Const::Room_Field_GameNum] = 0;			//游戏第几局
        $r_mkv[Redis_Const::Room_Field_Status] = Game::RoomStatus_Waiting;				//房间状态，1等待、2进行中、3关闭
        $r_mkv[Redis_Const::Room_Field_Creator] = $account_id;  //房间创建者
        $r_mkv[Redis_Const::Room_Field_Scoreboard] = "{}";
        $r_mkv[Redis_Const::Room_Field_StartTime] = -1;
        $r_mkv[Redis_Const::Room_Field_Password] = $roomInfo["password"] ;
        $r_mkv[Redis_Const::Room_Field_TicketCount] = $spend_ticket_count;
        RedisService::getInstance()->updateRoomInfo($room_id, $r_mkv);

        $r_rule[Redis_Const::RoomRule_Field_DefaultScore] = $data["default_score"];//Game::Default_Score;		//开局默认分数
        $r_rule[Redis_Const::RoomRule_Field_ChipType] = $data["chip_type"];
        $r_rule[Redis_Const::RoomRule_Field_DisablePkScore] = $data["disable_pk_score"];
        $r_rule[Redis_Const::RoomRule_Field_DisableLook] = $data["disable_look"];
        $r_rule[Redis_Const::RoomRule_Field_DisablePkMen] = $data["disable_pk_men"];
        $r_rule[Redis_Const::RoomRule_Field_Onlybig] = $data['only_big'];
        $r_rule[Redis_Const::RoomRule_Field_UpperLimit] = $data["upper_limit"];
        $r_rule[Redis_Const::RoomRule_Field_XiPai] = $data["xipai_score"];
        $r_rule[Redis_Const::RoomRule_Field_PlayerCount] = $data["player_count"];
        $r_rule[Redis_Const::RoomRule_Field_TotalNum] = $data["total_num"];
        RedisService::getInstance()->updateRoomRule($room_id, $r_rule);

        //扣除房卡  房主扣卡模式
        MysqlService::getInstance()->balanceTicket($room_id, $account_id, $spend_ticket_count);

        //观战功能 建房时设定清房定时器
        $this->setupClearRoomPassiveTimer($room_id);
        $this->writeLog("[$room_id] ($account_id) 创建房间".$roomInfo['room_number']);
        return array("result"=>CodeConst::Success_CreateRoom,"operation"=>$operation,"data"=>$roomInfo,"result_message"=>"创建房间");
    }


    public function prepareJoinRoom($arrData){
        $result = array();
        $data 			= $arrData['data'];
        $operation 		= $arrData['operation'];
        $account_id 	= $arrData['account_id'];
        $session 		= $arrData['session'];

        if(false == Tools::getInstance()->checkRequestSession($account_id,$session)){
            return OPT_CONST::NO_RETURN;
        }

        if(!(isset($data['room_number'])&& $data['room_number'] > 0) ){
            $this->logMessage('error', "function(PrepareJoinRoom):lack of room_number"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"room_number");
        }

        //判断房间是否存在
        $roomData = MysqlService::getInstance()->getRoomByRoomNumber($data['room_number']);
        if(!$roomData){
            $this->logMessage('error', "function(prepareJoinRoom):room(".$data['room_number'].") not exist"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>CodeConst::Error_RoomNotExist,"operation"=>$operation,"data"=>[],"result_message"=>"房间不存在");
        } else {
            if($roomData['is_close']){
                return array("result"=>CodeConst::Error_RoomIsClosed, "operation"=>$operation,"data"=>array('room_status'=>4),"result_message"=>"房间已关闭");
            }
            $room_id = $roomData['room_id'];
        }

        //获取维护公告
        $alert_type = -1;
        $announcement_result = MysqlService::getInstance()->getGameAnnouncement($account_id);
        if(is_array($announcement_result)) {
            $alert_type = $announcement_result['alert_type'];
            $alert_text = $announcement_result['alert_text'];
        }
        if($alert_type == 4) {
            $result['alert_type'] = $alert_type;
            return array("result"=>CodeConst::Error_Announcement,"operation"=>$operation,"data"=>['alert_type'=>$alert_type],"result_message"=>$alert_text);
        }

        //房间参数
        $roomInfo = RedisService::getInstance()->queryRoomInfo($room_id);
        $roomRule = RedisService::getInstance()->queryRoomRule($room_id);

        //获取房间所有玩家
        $playerIdList = RedisService::getInstance()->queryRoomMembers($room_id);
        if($user_count = count($playerIdList)>0){
            $playerList = MysqlService::getInstance()->getAccountListByID($playerIdList,"account_id,nickname");
        }
        $roomInfo['can_join'] = $user_count < $roomRule[Redis_Const::RoomRule_Field_PlayerCount];
        return array("result"=>CodeConst::Success_PrepareJoinRoom,"operation"=>$operation,"data"=>['roomInfo'=>$roomInfo,'roomRule'=>$roomRule,'playerList'=>$playerList],"result_message"=>"进房询问");
    }

    public function joinRoom($arrData){
        $data 			= $arrData['data'];
        $operation 		= $arrData['operation'];
        $account_id 	= $arrData['account_id'];
        $client_id 		= $arrData['client_id'];
        $session 		= $arrData['session'];
        if(false == Tools::getInstance()->checkRequestSession($account_id,$session)){
            return OPT_CONST::NO_RETURN;
        }
        if(!(isset($data['room_number'])&& $data['room_number'] > 0) ) {
            $this->logMessage('error', "function(joinRoom):lack of room_number"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"room_number");
        }
        $room_number = $data['room_number'];

        //判断房间是否存在
        $roomData = MysqlService::getInstance()->getRoomByRoomNumber($room_number);
        if(!$roomData){
            $this->logMessage('error', "function(joinRoom):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>CodeConst::Error_RoomNotExist,"operation"=>$operation,"data"=>[],"result_message"=>"房间不存在");
        } else {
            $room_id = $roomData['room_id'];
            if($roomData['is_close']){
                return array("result"=>CodeConst::Error_RoomIsClosed, "operation"=>$operation,"data"=>array('room_status'=>4),"result_message"=>"房间已关闭");
            }
        }
        $roomRule = RedisService::getInstance()->queryRoomRule($room_id);
        //判断用户是否已加入房间
        if($serial_num = RedisService::getInstance()->querySerialNum($room_id, $account_id) ){//已加入
            //获取分数
            $account_score = RedisService::getInstance()->queryRoomScore($room_id, $account_id);
            $account_status = RedisService::getInstance()->queryAccountStatus($room_id, $account_id);
        } else {//未加入
            $serial_num = RedisService::getInstance()->joinRoomTransaction($room_id,$account_id, $roomRule[Redis_Const::RoomRule_Field_PlayerCount]);
            if(!$serial_num){
                return array("result"=>CodeConst::Error_RoomIsFull,"operation"=>$operation,"data"=>['alert_type'=>2],"result_message"=>"房间人数已满");
            }
            //添加默认分数
            $account_score = 0;
            //更新用户初始积分
            RedisService::getInstance()->updateRoomScore($room_id, $account_id, $account_score);
            //首次进房初始状态
            RedisService::getInstance()->updateAccountStatus($room_id, $account_id, Game::AccountStatus_Initial);
        }
        GatewayService::getInstance()->joinGatewayRoom($client_id, $room_id, $account_id);

        
        $setting = GameData::getInstance()->queryRoomSetting($room_id);
        //获取房间当前局数

        $room_ary['room_id'] = $room_id;
        $room_ary['room_number'] = $room_number;
        $room_ary['room_status'] = $setting[Redis_Const::Room_Field_Status];
        $room_ary['account_score'] = $account_score;
        $room_ary['account_status'] = $account_status;
        $room_ary['online_status'] = GameData::getInstance()->queryOnlineStatus($room_id, $account_id);
        $room_ary['serial_num'] = $serial_num;
        $room_ary['game_num'] = $setting[Redis_Const::Room_Field_GameNum];
        $room_ary['total_num'] = $setting[Redis_Const::Room_Field_TotalNum];
        $room_ary['scoreboard'] = isset($setting[Redis_Const::Room_Field_Scoreboard]) ? json_decode($setting[Redis_Const::Room_Field_Scoreboard]) : new \stdClass();
        $room_ary['ticket_count'] =$setting[Redis_Const::Room_Field_TicketCount];
        $room_ary['chip_type'] = $setting[Redis_Const::Room_Field_ChipType];
        $room_ary['disable_pk_100'] =$setting[Redis_Const::Room_Field_DisablePk100];
        $room_ary['disable_look'] =$setting[Redis_Const::Room_Field_DisableLook];
        $room_ary['disable_pk_men'] =$setting[Redis_Const::Room_Field_DisablePkMen];
        $room_ary['upper_limit'] =$setting[Redis_Const::Room_Field_UpperLimit];
        $room_ary['xipai_score'] =$setting[Redis_Const::Room_Field_XiPai];

        $card_info = array();
        $card_type = 0;
        if(GameData::getInstance()->querySeenCard($room_id, $account_id)){	//已经看过牌的
            $card_info = GameData::getInstance()->queryPlayerCard($room_id, $account_id);
            $value = GameData::getInstance()->_cardValue($card_info);
            $card_type = substr($value, 0, 1);
        }

        $room_ary['cards'] = $card_info;
        $room_ary['card_type'] = $card_type;

        $room_ary['benchmark'] = GameData::getInstance()->queryBenchmark($room_id);
        $room_ary['pool_score'] = GameData::getInstance()->queryPoolScore($room_id);


        //推送房间信息
        $room_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>$operation,"data"=>$room_ary,"result_message"=>"入房成功");
        $this->pushMessageToCurrentClient($room_return);

        //返回所有玩家状态给进房玩家
        $allGamer =  GameData::getInstance()->getGamerInfo($room_id);
        if(is_array($allGamer)) {
            $currentGamer_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>"AllGamerInfo","data"=>$allGamer,"result_message"=>"所有玩家状态");
            $this->pushMessageToCurrentClient($currentGamer_return);
        }

        $playerStatus = GameData::getInstance()->queryPlayingStatus($room_id, $account_id);
        $this->pushMessageToCurrentClient($playerStatus);

        GameData::getInstance()->updateLremGuestList($room_id, $account_id);
        //返回所有观战者给当前玩家
        $allGuest = GameData::getInstance()->getGuestInfo($room_id);
        if(is_array($allGuest))
        {
            $currentGamer_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>"AllGuestInfo","data"=>$allGuest,"result_message"=>"所有观战者状态");
            $this->pushMessageToCurrentClient($currentGamer_return);
        }

        //推送当前玩家状态给其他玩家
        $currentGamer = $allGamer[$account_id];
        if(is_array($currentGamer))
        {
            $currentGamer_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>"UpdateGamerInfo","data"=>$currentGamer,"result_message"=>"某玩家状态");
            $this->pushMessageToGroup($room_id, $currentGamer_return, $client_id);
        }

        //显示房间目前的倒计时
        $limit = $setting[Redis_Const::Room_Field_GameNum] > 0 ? Game::LimitTime_Ready : Game::LimitTime_StartGame;

        if($setting[Redis_Const::Room_Field_Status] == Game::RoomStatus_Waiting && ($countdown = GameData::getInstance()->queryCountdown($room_id, $limit)) > 0){
            $arr = array("result"=>0,"operation"=>"StartLimitTime","data"=>array('limit_time' => $countdown),"result_message"=>"开始倒计时");
            $this->pushMessageToCurrentClient($arr);
        }
        $this->writeLog("[$room_id] $account_id 进入房间");
        return OPT_CONST::NO_RETURN;
    }
    /**
     * 准备
     * @param $arrData
     * @return array|int
     */
    public function readyStart($arrData){
        $result = array();

        $data 			= $arrData['data'];
        $operation 		= $arrData['operation'];
        $account_id 	= $arrData['account_id'];
        $client_id 		= $arrData['client_id'];

        $session 		= $arrData['session'];
        if(false == Tools::getInstance()->checkRequestSession($account_id,$session)){
            return OPT_CONST::NO_RETURN;
        }

        if(!isset($data['room_id']) || trim($data['room_id']) == G_CONST::EMPTY_STRING) {
            $this->logMessage('error', "function(readyStart):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"room_id");
        }

        $room_id = $data['room_id'];
        $is_legal = GameData::getInstance()->checkRequestClientLegal($client_id,$room_id,$account_id);
        if(!$is_legal) {
            $this->logMessage('error', "function(checkRequestClientLegal):illegal opt: account_id($account_id) room_id($room_id)"." in file".__FILE__." on Line ".__LINE__);
            //推送强制下线
            $illegal_message = array("result"=>"-203","result_message"=>"illegal opt");
            $this->pushMessageToCurrentClient($illegal_message);
            return OPT_CONST::NO_RETURN;
        }

        //获取玩家当前状态，是否未准备
        $rStatus = GameData::getInstance()->queryAccountStatus($room_id, $account_id);
        if(Redis_Const::DATA_NONEXISTENT === $rStatus || !in_array($rStatus, [Game::AccountStatus_Initial, Game::AccountStatus_Notready])  )
        {
            $this->writeLog("function(readyStart):account($account_id) status($rStatus) invalid"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"状态异常");
        }

        //更新用户状态
        GameData::getInstance()->updateAccountStatus($room_id, $account_id, Game::AccountStatus_Ready);

        $this->startGame($room_id);

        return OPT_CONST::NO_RETURN;
    }

    public function guestRoom($arrData){

    }


    public function readyCancel($arrData){

    }

    public function pullRoomInfo($arrData){

    }
    public function historyScoreboard($arrData){

    }
    public function lastScoreboard($arrData){

    }

    /**
     * 开局
     * @param $room_id
     * @param bool $passive_by_timer
     * @return bool
     */
    protected function startGame($room_id, $passive_by_timer=false)
    {
        $ready_user = GameData::getInstance()->queryReadyUser($room_id);
        $in_room_array = GameData::getInstance()->queryInRoomUser($room_id);
        $ready_count = count($ready_user);
        $online_count = count($in_room_array);

        //准备人数 大于等于2 且 准备人数 等于 在线人数
        $this->writeLog("[$room_id] 准备:".$ready_count."人   "."在线:".$online_count."人");

        if($ready_count >=2) {
            if($passive_by_timer || $ready_count == $online_count){

                $pre_readyUser_ary = array();		//已准备用户数组-前
                $rear_readyUser_ary = array();		//已准备用户数组-后
                $is_rear = true;

                $ready_in_room_user = array_intersect($in_room_array, $ready_user); //在房的已准备用户
                if(count($ready_in_room_user) < 2){
                    $this->writeLog("在房".$room_id."的已准备用户数量:".count($ready_in_room_user)." 不能开局 in file".__FILE__." on Line ".__LINE__);
                    return false;
                }

                $success = GameData::getInstance()->setRoomStatusTransaction($room_id, 1, 2);
                if(!$success){
                    $this->writeLog("并发 start game，忽略。room id:".$room_id."。in file".__FILE__." on Line ".__LINE__);
                    return false;
                }

                //开始游戏
                //参与游戏的都需要checked
                $ready_in_room_user = GameData::getInstance()->ticketCheckTransaction($room_id, $ready_in_room_user);  //参与游戏玩家
                if(count($ready_in_room_user) < 2){	//异常情况
                    GameData::getInstance()->setRoomStatusTransaction($room_id, 2, 1);	//修正房间状态
                    $this->writeLog("[$room_id]的参与玩家数:".count($ready_in_room_user)." 不能开局 in file".__FILE__." on Line ".__LINE__);
                    return false;
                }

                $banker_id = GameData::getInstance()->queryBanker($room_id);

                foreach($ready_in_room_user as $account_id)
                {
                    if(in_array($account_id, $ready_in_room_user))
                    {
                        if($is_rear)
                        {
                            $rear_readyUser_ary[] = $account_id;
                        }
                        else
                        {
                            $pre_readyUser_ary[] = $account_id;
                        }
                    }

                    if($account_id == $banker_id)
                    {
                        $is_rear = false;
                    }
                }

                $readyUser_ary = array_merge($pre_readyUser_ary,$rear_readyUser_ary);

                $next_banker_id = $readyUser_ary[0];

                if(!$passive_by_timer){
                    //取消倒计时
                    $this->deleteRoomTimer($room_id);
                }

                GameData::getInstance()->deleteCardKey($room_id);
                GameData::getInstance()->deleteSeenCardKey($room_id);
                GameData::getInstance()->deleteChipKey($room_id);

                $setting = GameData::getInstance()->queryRoomSetting($room_id);

                $only_big = $setting[Redis_Const::Room_Field_Onlybig];
                $only_big = $only_big > 0 ? true : false;
                $readyUserCount = count($readyUser_ary);  //游戏中玩家数量
                $player_cards = GameData::getInstance()->dealCard($readyUserCount,$only_big);  //发牌

                foreach ($readyUser_ary as $account_id) {
                    //玩家状态变成闷牌状态
                    GameData::getInstance()->updateAccountStatus($room_id, $account_id, Game::AccountStatus_Invisible);
                    //设置每局玩家手牌hash
                    $account_cards = array_pop($player_cards);
                    GameData::getInstance()->updatePlayerCard($room_id, $account_id, $account_cards);
                }

                //设置每局玩家顺序list
                $play_member = $readyUser_ary;

                //删除每局玩家顺序list 再装入本局玩家
                GameData::getInstance()->deletePlayMemberKey($room_id);
                GameData::getInstance()->pushPlayMember($room_id,$play_member);

                //重设每局游戏参数
                $parameter_ary[Redis_Const::Play_Field_PoolScore] = 0;// Game::Default_Score * $ready_count;
                $parameter_ary[Redis_Const::Play_Field_Benchmark] = Game::Default_Score;

                $parameter_ary[Redis_Const::Play_Field_ActiveUser] =  $next_banker_id;
                $mset_result = $Redis_Model->hmsetField($Play_Key,$parameter_ary);


                $Room_mkv[Redis_Const::Room_Field_Status] = 2;  //房间状态，1等待、2进行中、3关闭
                $Room_mkv[Redis_Const::Room_Field_Banker] = $next_banker_id;
                $mset_result = $Redis_Model->hmsetField($Room_Key,$Room_mkv);

                //房间轮数与局数更新
                GameData::getInstance()->updateGameNumberRound($room_id);

                //底注
                foreach($readyUser_ary as $account_id)
                {
                    GameData::getInstance()->balanceScore($room_id, $account_id, $setting[Redis_Const::Room_Field_DefaultScore]);
                }

                $player_status = array();
                foreach ($play_member as $player_id) {
                    if($player_id == $next_banker_id){
                        $player_status[] = array(
                            "account_id"=> $player_id,
                            "account_status"=> Game::AccountStatus_Invisible,		 //5; 初始是闷牌状态
                            "online_status" => GameData::getInstance()->queryOnlineStatus($room_id, $player_id),
                            "playing_status"=> Game::PlayingStatus_Betting, //2;  下注中
                            "limit_time" => Game::LimitTime_Betting,
                            'can_open' =>  0,
                            'can_look' => GameData::getInstance()->lookConditon($room_id, $player_id)
                        );
                    } else {
                        $player_status[] = array(
                            "account_id"=> $player_id,
                            "account_status"=> Game::AccountStatus_Invisible,		 //5; 初始是闷牌状态
                            "online_status" => GameData::getInstance()->queryOnlineStatus($room_id, $player_id),
                            "playing_status"=> Game::PlayingStatus_Waiting, //1 等待别人中
                            "limit_time" => 0
                        );
                    }
                }

                //设置自动弃牌定时器
                $this->setupDiscardPassiveTimer($room_id, $next_banker_id);

                //推送开始
                $arr = array("result"=>0,"operation"=>"GameStart","data"=>$player_status,"result_message"=>"游戏开始了");
                $this->pushMessageToGroup($room_id, $arr);

            } else {
                if(GameData::getInstance()->queryTimerTime($room_id) == -1 ){
                    if($ready_count == 2){	//第二个人准备就删掉自动清理房间定时器
                        $this->deleteRoomTimer($room_id);
                    }

                    $this->setupStartGamePassiveTimer($room_id);
                }
            }
        }

        return true;
    }


    /**
     * 断线
     * @param $arrData
     * @return bool
     */
    public function userDisconnected($arrData) {
        if(!isset($arrData['gaming_roomid']) || trim($arrData['gaming_roomid']) == G_CONST::EMPTY_STRING) {
            return false;
        }
        if(!isset($arrData['account_id']) || trim($arrData['account_id']) == G_CONST::EMPTY_STRING) {
            return false;
        }

        $room_id 		= $arrData['gaming_roomid'];
        $account_id 	= $arrData['account_id'];
        $client_id 		= $arrData['client_id'];

        if(GameData::getInstance()->queryOnlineStatus($room_id, $account_id)){
            $this->writeLog("[$room_id] [$account_id] is still in room");
            return true;
        }

        $this->writeLog("[$room_id] ($account_id) 离线");

        //获取房间状态
        $room_status = GameData::getInstance()->queryRoomSetting($room_id,Redis_Const::Room_Field_Status);
        if($room_status === Redis_Const::DATA_NONEXISTENT || $room_status == Game::RoomStatus_Closed ){	//房间已经废弃或未激活
            return true;
        }

        //没开局玩过的用户离线，自动从房间中退出
        $flag = GameData::getInstance()->leaveSeatTransaction($room_id,$account_id);
        if(2 == $flag){			//unchecked 离座
            $account_status = Game::AccountStatus_Initial;
        } else if(1 == $flag){	//checked 离座
            $account_status = $this->queryAccountStatus($room_id, $account_id);
            if($account_status == Game::AccountStatus_Ready){	//准备状态下断线， 变为未准备
                $account_status = Game::AccountStatus_Notready;
            }
        } else {
            $account_status = Game::AccountStatus_Initial;
        }

        $onlineStatus = GameData::getInstance()->updateAccountStatus($room_id, $account_id, $account_status );
        $this->pushMessageToGroup($room_id, $onlineStatus);


        if($room_status == Game::RoomStatus_Waiting) {
            $ready_count =  GameData::getInstance()->queryReadyCount($room_id);
            if($ready_count < 2){
                //取消倒计时
                $this->deleteRoomTimer($room_id);
                $arr = array("result"=>0,"operation"=>"CancelStartLimitTime","data"=>array(),"result_message"=>"取消开局倒计时");
                $this->pushMessageToGroup($room_id, $arr);
            } else {
                $this->startGame($room_id);
            }
        }

        //判断是否全部人离线
        $clients_of_groupid =GameData::getInstance()->getClientSessionsByGroup($room_id);
        if(count($clients_of_groupid) == 0) {
            $this->setupClearRoomPassiveTimer($room_id);
        }

        return true;
    }
}